package cn.hg.solon.youcan.framework.web.admin.filter;

import java.util.Date;

import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.text.CharSequenceUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.http.meta.HttpStatus;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hg.solon.youcan.framework.web.admin.annotation.Logging;

/**
 * @author 胡高
 */
@Component(index = Integer.MAX_VALUE - 10000)
public class ActionFilter implements Filter {
    protected static Logger log = LoggerFactory.getLogger(ActionFilter.class);

    private static String adminPattern = "/admin";

    /* (non-Javadoc)
     * @see org.noear.solon.core.handle.Filter#doFilter(org.noear.solon.core.handle.Context, org.noear.solon.core.handle.FilterChain)
     */
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        boolean isAdmin = CharSequenceUtil.startWith(ctx.pathNew(), adminPattern);

        Date start = DateUtil.now();
        try {
            chain.doFilter(ctx);

            // 可能上级链已完成处理
            if (ctx.getHandled()) {
                return;
            }

            if(!ctx.getHandled()){
                ctx.status(HttpStatus.HTTP_NOT_FOUND);

                if (isAdmin) {
                    // 统一的结果处理
                    ActionResultHandler.handle(ctx, null);
                }
            }
        } catch (Throwable e) {
            if (isAdmin) {
                // 统一的异常处理
                ActionResultHandler.handle(ctx, e);
            } else {
                throw e;
            }
        } finally {
            if (isAdmin) {
                Date end = DateUtil.now();
                if (Solon.cfg().isDebugMode() && ObjUtil.isNotNull(ctx.action())) {
                    // 打印Action报告
                    ActionReporter.report(ctx, end.getTime() - start.getTime());
                }

                if (ObjUtil.isNotNull(ctx.action())) {
                    Logging logging = ctx.action().method().getAnnotation(Logging.class);
                    if (ObjUtil.isNotNull(logging)) {
                        // 对有Log注解的操作记录其操作日志
                        OperateLogReporter.logging(ctx, logging, start, end);
                    }
                }

                UserOnlineSyncHandler.handle(ctx);
            }
        }
    }

}
